
#pragma once

public ref struct PointR
{
private:
	int x;
	int y;
public:
	PointR(){}
	~PointR(){}
	!PointR(){}
	PointR(int _x, int _y): x(_x), y(_y) {}
	void PrintPt()
	{
		System::Console::WriteLine("(X:{0},Y:{1})",x,y);
	}

	// no default copy constructor
	PointR(const PointR% pt)
	{
		x = pt.x;
		y = pt.y;
	}
	// no default operator=
	PointR% operator=(const PointR% pt)
	{
		x = pt.x;
		y = pt.y;
		return *this;
	}
};

public ref class LineR
{
private:
    PointR m_ptFirst;
    PointR m_ptEnd;
public :
	LineR(){}
    LineR(PointR first,PointR end)
    {
        m_ptFirst = first;
        m_ptEnd = end;
    }
	LineR(PointR^ first,PointR^ end)
	{
		m_ptFirst = *first;
		m_ptEnd = *end;
	}
	~LineR(){}
	!LineR(){}
	void PrintLine()
	{
		System::Console::Write("StartPoint:");
		m_ptFirst.PrintPt();
		System::Console::Write("EndPoint:");
		m_ptEnd.PrintPt();
	}
}; 

void Test3()
{
	PointR pt(10,10);
	pt.PrintPt();

	// can declare pointer variable
	//PointR* pPt = new PointR(100,100);

	PointR^ rPt = gcnew PointR(1,1);
	rPt->PrintPt();
	// you can delete it or not
	delete rPt;
	
	PointR^ p1 = gcnew PointR(30,30);
	PointR^ p2 = gcnew PointR(40,40);
	LineR^ rLine = gcnew LineR(p1,p2);
	rLine->PrintLine();
	LineR^ rLine2 = gcnew LineR(*p1,*p2);
	rLine2->PrintLine();

	LineR line(*p1,*p2);	
	line.PrintLine();
	LineR line2(p1,p2);
	line2.PrintLine();
	
	// can not declare pointer variable
	//LineR* pLine = new LineR(PointR(300,300), PointR(400,400));

	LineR^ rTempLine = gcnew LineR(PointR(3,3), PointR(4,4));
	rTempLine->PrintLine();
	// you can delete it or not
	delete rLine;	
}
